<template>
  <v-chart autoresize :option="option" :manual-update="true" ref="pieChartRef" />
</template>

<script lang="ts">
  import { defineComponent, type PropType, ref, watch } from 'vue';
  import { use } from 'echarts/core';
  import { TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components';
  import { PieChart } from 'echarts/charts';
  import { LabelLayout } from 'echarts/features';
  import { CanvasRenderer } from 'echarts/renderers';
  import VChart from 'vue-echarts';
  import type DashboardComponentType from '@/visual/commons/types/dashboard-component-type';
  import type PieChartOptionType from '@/visual/commons/types/pie-chart-option-type';
  import CommonUtil from '@/visual/commons/utils/common-util';
  import LogUtil from '@/visual/commons/utils/log-util';
  import { echartPieDataSourceConst } from '@/visual/commons/consts/dashboard-const';
  import { useDashboardStore } from '@/visual/stores/dashboard';

  use([TooltipComponent, LegendComponent, TitleComponent, PieChart, CanvasRenderer, LabelLayout]);

  export default defineComponent({
    name: 'PieChart',
    components: {
      VChart,
    },
    props: {
      compData: {
        type: Object as PropType<DashboardComponentType<PieChartOptionType>>,
        default: () => {
          return {};
        },
      },
    },
    emits: ['update:compData'],
    setup(props, { emit }) {
      const useDashboard = useDashboardStore();
      const option = ref<any>({});
      const pieChartRef = ref();
      const isInit = ref(true);

      /**
       * 获取数据
       */
      const getData = (item) => {
        return new Promise((resolve) => {
          if (item && item.dataSource) {
            // json数据
            if (item.dataSource.type === echartPieDataSourceConst.json) {
              let json = null;
              try {
                json = JSON.parse(item.dataSource.jsonConfig.data);
              } catch (e) {
                json = null;
              }
              resolve(json ? json : []);
            }

            //http数据
            if (item.dataSource.type === echartPieDataSourceConst.httpRequest) {
              setTimeout(() => {
                let json = null;
                try {
                  json = JSON.parse(item.dataSource.jsonConfig.data);
                } catch (e) {
                  json = null;
                }
                resolve(json ? json : []);
              }, 2000);
            }
          } else {
            resolve([]);
          }
        });
      };

      /**
       * 构建选项
       */
      const buildOpt = () => {
        let tooltipFormatter: string | Function = '';
        if (
          props &&
          props.compData &&
          props.compData.componentProps &&
          props.compData.componentProps.tooltip &&
          props.compData.componentProps.tooltip.formatter
        ) {
          tooltipFormatter = (params) => {
            return CommonUtil.expressionExe(
              props?.compData?.componentProps?.tooltip?.formatter,
              params
            );
          };
        }

        const series: any = [];
        const seriesPromise = new Promise((resolve) => {
          if (
            props &&
            props.compData &&
            props.compData.componentProps &&
            props.compData.componentProps.series &&
            props.compData.componentProps.series &&
            props.compData.componentProps.series.length
          ) {
            LogUtil.info({
              moduleName: 'pieChart',
              msg: 'build pie option',
              prop: false
            });

            props.compData.componentProps.series.map((item) => {
              const seriesRadius: string[] = [];
              if (item && item.radius && item.radius.length) {
                seriesRadius.push(item.radius[0] + '%');
                seriesRadius.push(item.radius[1] + '%');
              }

              const seriesCenter: string[] = [];
              if (item && item.center && item.center.length) {
                seriesCenter.push(item.center[0].value + item.center[0].unit);
                seriesCenter.push(item.center[1].value + item.center[1].unit);
              }

              let labelFormatter: string | Function = '';

              if (item && item.label && item.label.formatter) {
                labelFormatter = (params) => {
                  return CommonUtil.expressionExe(item?.label?.formatter, params);
                };
              }

              let emphasisLabelFormatter: string | Function = '';

              if (item && item.emphasis && item.emphasis.label && item.emphasis.label.formatter) {
                emphasisLabelFormatter = (params) => {
                  return CommonUtil.expressionExe(item?.emphasis?.label?.formatter, params);
                };
              }

              //获取数据
              getData(item).then((seriesData) => {
                series.push({
                  name: item.name,
                  type: 'pie',
                  radius: seriesRadius,
                  avoidLabelOverlap: item.avoidLabelOverlap,
                  roseType: item.roseType,
                  color: item.color,
                  cursor: item.cursor,
                  selectedMode: item.selectedMode,
                  selectedOffset: item.selectedOffset,
                  legendHoverLink: item.legendHoverLink,
                  stillShowZeroSum: item.stillShowZeroSum,
                  startAngle: item.startAngle,
                  minAngle: item.minAngle,
                  minShowLabelAngle: item.minShowLabelAngle,
                  zlevel: item.zlevel,
                  itemStyle: item.itemStyle,
                  center: seriesCenter,
                  label: {
                    show: item.label?.show,
                    position: item.label?.position,
                    color: item.label?.color,
                    fontStyle: item.label?.fontStyle,
                    fontWeight: item.label?.fontWeight,
                    fontSize: item.label?.fontSize,
                    rotate:
                      item.label?.rotate?.select === 'true' ? true : item.label?.rotate?.value,
                    overflow: item.label?.overflow,
                    ellipsis: item.label?.ellipsis,
                    backgroundColor: item.label?.backgroundColor,
                    borderColor: item.label?.borderColor,
                    borderWidth: item.label?.borderWidth,
                    borderType: item.label?.borderType,
                    borderRadius: item.label?.borderRadius,
                    padding: item.label?.padding,
                    lineHeight: item.label?.lineHeight,
                    width: item.label?.width,
                    height: item.label?.height,
                    formatter: labelFormatter && labelFormatter.length ? labelFormatter : null,
                  },
                  labelLine: item.labelLine,
                  emphasis: {
                    scale: item.emphasis?.scale,
                    scaleSize: item.emphasis?.scaleSize,
                    focus: item.emphasis?.focus,
                    blurScope: item.emphasis?.blurScope,
                    label: {
                      show: item.emphasis?.label?.show,
                      color: item.emphasis?.label?.color,
                      fontStyle: item.emphasis?.label?.fontStyle,
                      fontWeight: item.emphasis?.label?.fontWeight,
                      fontSize: item.emphasis?.label?.fontSize,
                      rotate:
                        item.emphasis?.label?.rotate?.select === 'true'
                          ? true
                          : item.emphasis?.label?.rotate?.value,
                      overflow: item.emphasis?.label?.overflow,
                      ellipsis: item.emphasis?.label?.ellipsis,
                      backgroundColor: item.emphasis?.label?.backgroundColor,
                      borderColor: item.emphasis?.label?.borderColor,
                      borderWidth: item.emphasis?.label?.borderWidth,
                      borderType: item.emphasis?.label?.borderType,
                      borderRadius: item.emphasis?.label?.borderRadius,
                      padding: item.emphasis?.label?.padding,
                      lineHeight: item.emphasis?.label?.lineHeight,
                      width: item.emphasis?.label?.width,
                      height: item.emphasis?.label?.height,
                      formatter:
                        emphasisLabelFormatter && emphasisLabelFormatter.length
                          ? emphasisLabelFormatter
                          : null,
                    },
                    labelLine: item.emphasis?.labelLine,
                  },
                  data: seriesData,
                });

                resolve(true);
              });
            });
          } else {
            resolve(true);
          }
        });

        seriesPromise.then(() => {
          option.value = {
            title: {
              ...props.compData.componentProps?.title,
            },
            tooltip: {
              ...props.compData.componentProps?.tooltip,
              formatter: tooltipFormatter,
            },
            legend: {
              type: props.compData.componentProps?.legend?.type,
              zlevel: props.compData.componentProps?.legend?.zlevel,
              orient: props.compData.componentProps?.legend?.orient,
              padding: props.compData.componentProps?.legend?.padding,
              show: props.compData.componentProps?.legend?.show,
              top: props.compData.componentProps?.legend?.top?.value,
              bottom: props.compData.componentProps?.legend?.bottom?.value,
              left: props.compData.componentProps?.legend?.left?.value,
              right: props.compData.componentProps?.legend?.right?.value,
              textStyle: props.compData.componentProps?.legend?.textStyle,
            },
            series,
          };

          pieChartRef.value && pieChartRef.value.clear();
          pieChartRef.value && pieChartRef.value.setOption(option.value);
        });
      };

      /**
       * 构建主题
       */
      const buildTheme = () => {
        const data: any = {
          ...props.compData,
        };
        isInit.value = false;
        const themeConfig = useDashboard.getDashboardThemeConfig;

        console.info(themeConfig);
        //如果主题存在时
        if (themeConfig) {
          data.componentProps.series[0].color = ['red', 'blue', 'green', '#fdsfdd'];

          //不存在时还原
        } else {
          console.info(props.compData);
          data.componentProps.series[0].color = [...data.componentProps.defaultSeries.color];
        }

        emit('update:compData', data);
      };

      watch(
        () => useDashboard.getDashboardThemeConfig,
        () => {
          buildTheme();
        },
        { deep: true, immediate: false }
      );

      watch(
        () => props.compData.componentProps,
        () => {
          if (isInit.value) {
            buildTheme();
          } else {
            buildOpt();
          }
        },
        { deep: true, immediate: true }
      );

      return {
        option,
        pieChartRef,
      };
    },
  });
</script>

<style lang="less" scoped>
  @import './PieChart.less';
</style>
